'''
Created on 19/03/2010

@author: eh01
'''
from datastore.resource import Resource
from runtime.task import Task
import httplib
import logging
import re

application_uri_pattern = re.compile(r'/app/(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})')

class HTTPInterceptorTask(Task):
    """This class is a daemon task. It processes requests from httpserver::RequestHandler
    and return Spaces resources.

    *Usage examples*::

        example code

    *Common Arguments for Class methods*:
        <arguments>
    
    *Audience*:
        <audience>
    
    *Constants*:
        .. data:: constant_1
        
            constant_1 is used for ......
        
        .. data:: constant_2
        
            constant_2 is used for ......
    """

    def cb_start(self, method, uri, new_uri, result, context, **kwargs):
        """This function is called when the task starts. 
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param new_uri: <class> or <type>
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        
        self.logger.log(logging.DEBUG, "***************** uri (%s), new_uri (%s)" % (uri, new_uri))
        
        # Make sure we look for ALL Uris that are children of our task Uri.
        # (i.e. make a collection of our Uri. 
        #
        # All 'put' messages to this task are interpreted as requests for Spaces Resources.
        #
        self.spaces_context.process(uri.listen, put='cb_delegate')
        
    def cb_delegate(self, method, uri, return_value, result, context, **kwargs):
        """This method looks at the request uri and delegates to the appropriate http handler.
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param return_value: Resource
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        requested_uri_string = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_URI)
        request_method = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_METHOD)
        
        # default empty resource for response
        rs = Resource();
        # depending on the requested uri and the http method, delegate to the appropriate task.
        if requested_uri_string == "/":
            pass       
        elif requested_uri_string == '/login' and request_method == 'GET':
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'login')
        elif requested_uri_string == '/login' and request_method == 'POST':
            task_uri = context.uri('task:')
            res_uri = context.put(task_uri.eplanning.reference.logintask.login.submit, return_value)
            rs = context.get_wait(res_uri.response)            
        elif requested_uri_string == '/menu' and request_method == 'GET':
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'menu')       
        elif requested_uri_string == '/admin' and request_method == 'GET':
            task_uri = context.uri('task:')
            rs = context.get(task_uri.eplanning.reference.admintask.admin.menu)            
        elif requested_uri_string == '/admin/spear-integration-configuration' and request_method == 'GET':
            task_uri = context.uri('task:')
            res = context.get(task_uri.eplanning.reference.admintask.add('spear-integration-configuration'))
            rs.spear_integration_configuration = res               
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'configure-spear-integration')
        elif requested_uri_string == '/admin/spear-integration-configuration' and request_method == 'POST':
            post_data = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_DATA)
            if post_data['operation'] == 'Save & Close':
                task_uri = context.uri('task:')
                context.put(task_uri.eplanning.reference.admintask.add('spear-integration-configuration'), return_value)
            rs.http_response_code = httplib.FOUND
            rs.http_headers = {'Location': '/admin'}
        elif requested_uri_string == '/admin/edais-connectivity-test' and request_method == 'GET':
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'perform-edais-connectivity-test')
        elif requested_uri_string == '/admin/edais-connectivity-test' and request_method == 'POST':
            post_data = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_DATA)
            if post_data['operation'] == 'Test Connection':
                task_uri = context.uri('task:')
                res_uri = context.put(task_uri.eplanning.reference.admintask.add('edais-connectivity-test'), return_value)
                res = context.remove(res_uri)
                rs.result = res    
                rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'perform-edais-connectivity-test')
            elif post_data['operation'] == 'Cancel':
                rs.http_response_code = httplib.FOUND
                rs.http_headers = {'Location': '/admin'}
        elif requested_uri_string == '/app-list' and request_method == 'GET':
            task_uri = context.uri('task:')
            rs = context.get(task_uri.eplanning.reference.apptask.applist)            
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'app-list')
        elif requested_uri_string == '/app' and request_method == 'GET':
            task_uri = context.uri('task:')
            rs = context.get(task_uri.eplanning.reference.apptask.app)
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'create-app')  
        elif application_uri_pattern.match(str(requested_uri_string)) and request_method == 'GET':
            task_uri = context.uri('task:')
            requested_uri_string = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_URI)
            app_id = application_uri_pattern.match(str(requested_uri_string)).group(1)
            form_rs = context.get(task_uri.eplanning.reference.apptask.view.app.add(app_id))            
            rs.form = form_rs
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'app')
        elif requested_uri_string == '/new-app' and request_method == 'GET':
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'new-app')     
        elif requested_uri_string == '/new-app' and request_method == 'POST':
            task_uri = context.uri('task:') 
            post_data = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_DATA)
            if post_data['operation'] == 'OK':
                res_uri = context.put(task_uri.eplanning.reference.apptask.new.app, return_value)
                rs = context.get_wait(res_uri.response)   
            elif post_data['operation'] == 'Cancel':
                rs.http_response_code = httplib.FOUND
                rs.http_headers = {'Location': '/app-list'}                            
        elif requested_uri_string == '/app' and request_method == 'POST':
            task_uri = context.uri('task:')
            res_uri = context.put(task_uri.eplanning.reference.apptask.app.collection(True), return_value)
            rs.http_response_code = httplib.FOUND
            rs.http_headers = {'Location': '/menu'}
        elif requested_uri_string == '/link-app' and request_method == 'GET':
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_RESULT, 'link-app')
        elif requested_uri_string == '/link-app' and request_method == 'POST':
            task_uri = context.uri('task:') 
            post_data = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_DATA)
            if post_data['operation'] == 'OK':
                res_uri = context.put(task_uri.eplanning.reference.apptask.link.app, return_value)
                rs = context.get_wait(res_uri.response)   
            elif post_data['operation'] == 'Cancel':
                rs.http_response_code = httplib.FOUND
                rs.http_headers = {'Location': '/app-list'}  
        elif requested_uri_string == '/app-action' and request_method == 'POST':
            post_data = return_value.get_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_REQUEST_DATA)
            rs.http_response_code = httplib.FOUND
            rs.http_headers = {'Location': post_data['action_url']}                                     
        else:
            rs.set_var(Resource.KEY_URI_SERVICES_TYPE_HTTP_SITE_ACTION_ERROR, "URI Not Found")
        id = context.uuid()
        request_uri = uri.requests.add(str(id))            
        context.put(request_uri.response, rs)
        return (True, request_uri.uri_copy())